﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using Cloud.Framework.Filter;
using Cloud.Framework.Model;
using Cloud.Framework.Validation;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;

namespace Cloud.Framework.Controller
{
    public class SuperController : Microsoft.AspNetCore.Mvc.Controller
    {
        public CurrentSysUser CurrentSysUser
        {
            get
            {
                return Request.HttpContext.Items["currentUser"] as CurrentSysUser;
            }
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            //写日志
            WriteLog(context);
            //验证提交的实体有效性
            if (HasActionAttribute<ValidateInput>(context) && IsAjax(context))
            {
                var errorMsg = GetValidateErrorMessage(context);
                if (!string.IsNullOrEmpty(errorMsg))
                {
                    context.Result = ErrorJsonResult(errorMsg);
                }
            }
            ViewBag.queryParas = Request.QueryString.Value;
            var action = ((ControllerActionDescriptor)context.ActionDescriptor);
            var actionName = action.ActionName;
            var controllerName = action.ControllerName;
            if (Request.Method == "GET")
            {
                ViewBag.CurrentPageUrl = Url.Action(actionName, controllerName) + (context.HttpContext.Request.QueryString.HasValue ? context.HttpContext.Request.QueryString.Value : "");

            }
            else
            {
                string paras = "?";
                foreach (var item in Request.Form)
                {
                    paras += "&" + item.Key + "=" + item.Value;
                }
                ViewBag.CurrentPageUrl = Url.Action(actionName, controllerName) + paras;

            }
            base.OnActionExecuting(context);
        }
        
        public JsonResult SuccessJsonResult(string info = null, object data = null)
        {
            return new JsonResult(new PostReturnJson() { code = 200, msg = info, data = data });
        }
        public JsonResult ErrorJsonResult(string errorMsg)
        {
            return new JsonResult(new PostReturnJson() { code = 500, msg = errorMsg });
        }
        public virtual RequestLogModel WriteLog(ActionExecutingContext context)
        {
            if (HasActionAttribute<NoLogAction>(context))
            {
                return null;
            }
            bool isNoWriteParameters = HasActionAttribute<NoWriteLogParametersAction>(context);
            var values = context.ActionDescriptor.RouteValues.Values;
            string controllerName = null;
            string actionName = null;
            int i = 0;
            foreach (var item in values)
            {
                if (i == 0)
                {
                    actionName = item;
                }
                if (i == 1)
                {
                    controllerName = item;
                }
                i++;
            }
            var httpContext = context.HttpContext;
            var method = context.HttpContext.Request.Method;
            string paramter = string.Empty;
            if (method == "POST")
            {
                var form = httpContext.Request.Form;
                foreach (var item in form)
                {

                    var key = item.Key;
                    if (key == "__RequestVerificationToken")
                    {
                        continue;
                    }
                    var value = item.Value;
                    paramter += "&" + key + "=" + value;
                }
                paramter = paramter.Substring(1);

            }
            else
            {
                paramter = httpContext.Request.QueryString.Value;
            }
            if (isNoWriteParameters)
            {
                paramter = "敏感参数不记录";
            }
            paramter = WebUtility.HtmlDecode(WebUtility.UrlDecode(paramter ?? ""));
            var ipAddress = httpContext.Connection.RemoteIpAddress.ToString();
            var url = httpContext.Request.Host.Value + httpContext.Request.Path;
            url = WebUtility.UrlDecode(url);
            var httpStatusCode = httpContext.Response.StatusCode;
            var user = CurrentSysUser;
            //todo 写日志
            RequestLogModel requestLogModel = new RequestLogModel()
            {
                Method = method,
                Parameter = paramter,
                ActionName = actionName,
                ControllerName = controllerName,
                IpAddress = ipAddress,
                Url = url,
                HttpStatusCode = httpStatusCode,
                CreateTime = DateTime.Now,
                SystemName = null,
                LoginId = user == null ? 0 : user.LoginID,
                LoginName = user == null ? null : user.LoginName

            };
            return requestLogModel;
        }
        public static bool IsAjax(ActionExecutingContext filterContext)
        {
            bool result = false;

            var xreq = filterContext.HttpContext.Request.Headers.ContainsKey("x-requested-with");
            if (xreq)
            {
                result = filterContext.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest";
            }

            return result;
        }
        public string GetValidateErrorMessage(ActionExecutingContext context)
        {
            if (!HasActionAttribute<ValidateInput>(context))
            {
                return null;
            }
            string errorMessage = string.Empty;
            foreach (var item in ModelState.Values)
            {
                if (item.Errors.Count > 0)
                {
                    for (int i = item.Errors.Count - 1; i >= 0; i--)
                    {
                        errorMessage += item.Errors[i].ErrorMessage;
                        errorMessage += "<br/>";
                    }
                }
            }
            return errorMessage;
        }
        public bool HasActionAttribute<T>(FilterContext context) where T : ActionFilterAttribute
        {
            bool isHas = false;
            var allFilters = context.Filters;
            foreach (var item in allFilters)
            {
                if (item.GetType().Equals(typeof(T)))
                {
                    isHas = true;
                    break;
                }
            }
            return isHas;

        }

    }
}
